package com.moonciki.artadmin.core.utils.excel;

import com.moonciki.artadmin.core.enums.ResponseEnum;
import com.moonciki.artadmin.core.exception.CustomException;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * excel 写入工具
 */
public abstract class ExcelWriter {
    @Getter
    protected String fileName;
    protected String[] columnArray;

    protected int sheetNumber;

    @Getter
    protected Workbook workbook;

    @Getter
    protected Sheet currentSheet;

    @Getter
    @Setter
    protected int rowIndex = 0;

    public static ExcelWriter getExcelWriter(String fileName, int sheetNumber, String sheetName) throws Exception{

        ExcelWriter excelWriter = new XExcelWriter(fileName, sheetNumber, sheetName);

        return excelWriter;
    }

    /**
     * 获取单元格值
     * @param cell
     * @return
     * @throws Exception
     */
    public void setValue(Cell cell, Object value) {
        if(value == null){
            //nothing to do
        }else if(value instanceof Boolean){
            Boolean trueValue = (Boolean) value;
            cell.setCellValue(trueValue);
        }else if (value instanceof Integer) {
            Integer trueValue = (Integer)value;
            cell.setCellValue(trueValue);
        } else if(value instanceof Double){
            Double trueValue = (Double)value;
            cell.setCellValue(trueValue);
        } else if(value instanceof Short){
            Short trueValue = (Short)value;
            cell.setCellValue(trueValue);
        } else if(value instanceof String){
            String trueValue = (String)value;
            cell.setCellValue(trueValue);
        } else{
            String trueValue = value + "";
            cell.setCellValue(trueValue);
        }
    }

    /**
     * 获得 byte 数据
     * @throws Exception
     */
    public byte[] getBytes() throws Exception{
        ByteArrayOutputStream bout = null;
        byte[] fileBytes = {};
        try {
            bout = new ByteArrayOutputStream();

            workbook.write(bout);

            fileBytes = bout.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(bout != null){
                bout.close();
            }
        }

        return fileBytes;
    }

    /**
     * 关闭资源
     */
    public void close(){
        if(workbook != null){
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void writeData(Object[] rowColumns) throws Exception {
        this.writeData(rowColumns, this.rowIndex);
        this.rowIndex++;
    }

    public void setTitleStyle(int count){
        //do set title style
    }

    /**
     * 写标题，标题包含格式
     * @param rowColumns
     * @throws Exception
     */
    public void writeTitleData(Object[] rowColumns) throws Exception {
        this.writeData(rowColumns, 0);
        this.setTitleStyle(rowColumns.length);
        this.rowIndex = 1;
    }

    public abstract void writeData(Object[] rowColumns, int rowNum) throws Exception;

    /**
     * 写入excel
     * @throws Exception
     */
    public void createExcel(List<Object[]> columnList) throws Exception {
        for(int i = 0; i<columnList.size(); i++){
            Object[] oneObjArray = columnList.get(i);
            writeData(oneObjArray, i);
        }
    }



}

/** 旧版本 **/
class HExcelWriter extends ExcelWriter{

    @Override
    public void writeData(Object[] rowColumns, int rowNum) throws Exception {
        throw CustomException.createException(ResponseEnum.sys_error.info("Not Support Yet!"));
    }

}

/** 新版本 **/
class XExcelWriter extends ExcelWriter{

    //protected XSSFWorkbook workbook;
    //protected XSSFSheet currentSheet;

    public XExcelWriter(String fileName, int sheetNumber, String sheetName) throws Exception{
        this.fileName = fileName;
        this.sheetNumber = sheetNumber;

        workbook = new XSSFWorkbook();

        currentSheet = workbook.createSheet(sheetName);
    }

    @Override
    public void writeData(Object[] rowColumns, int rowNum) throws Exception {
        XSSFRow xssfRow = (XSSFRow)currentSheet.getRow(rowNum);

        if(xssfRow == null){
            xssfRow = (XSSFRow)currentSheet.createRow(rowNum);
        }

        for(int j=0; j<rowColumns.length; j++){
            Object oneColumn = rowColumns[j];

            XSSFCell cell = xssfRow.createCell(j);

            if(oneColumn != null){
                setValue(cell, oneColumn);
            }
        }
    }

}